<?php
namespace modules\utils;

/**
 * @description: 树类
 * @author: 11921
 * @date: 2023-08-10 15:20:00
 * @method: getTree 
 */
class Tree
{
    /**
     * @description: 根据父级ID构建树型结构的数组,
     * @param {array} $list 列表
     * @param {array} $hidden 隐藏字段
     * @param {string} $pk 主键
     * @param {string} $pid 父级主键
     * @param {int} $root 根节点
     * @return array
     */

    public static function buildTree(array $list, array $hidden=[], $pk = 'id', $pid = 'pid', $root = 0) {
       //从根节点开始，基于pid递归构建树，删除使用过的节点
        $tree = [];
        foreach ($list as $key => $item) {
            if ($item[$pid] == $root) {
                $tree[] = $item;
                unset($list[$key]);
            }
        }
        foreach ($tree as $key => $item) {
            $tree[$key]['children'] = self::buildTree($list, $hidden, $pk, $pid, $item[$pk]);
        }
        return $tree;
    }  
    /**
     * @description: 生成随机多叉树结构数据，每个节点包含level(当前深度),children(子节点)
     * @param {int} $level_len 树层级深度
     * @param {array} $rand_num 每个节点的子节点的随机数量,使用函数range($rand_num[0],$rand_num[1])生成随机数
     * @return array 树结构数据
     */
    public static function generateTreeData(int $level_len=3, array $rand_num=[3,7]){
        // 验证输入参数
        if($level_len < 1) return [];
        if(count($rand_num) < 2) $rand_num = [3,7];
        list($min, $max) = array_map('intval', $rand_num);
        $min = min(max($min, 0), $max);
        $max = max($min, $max);
        
        // 递归生成树节点的闭包函数
        $createNode = function($currentLevel) use (&$createNode, $level_len, $min, $max) {
            $node = ['level' => $currentLevel, 'children' => []];
            
            // 达到最大层级不再生成子节点
            if($currentLevel >= $level_len) return $node;
            
            // 使用range生成子节点数量范围并随机选择
            $childCountRange = range($min, $max);
            $childCount = $childCountRange[array_rand($childCountRange)];
            
            // 生成子节点
            for($i = 0; $i < $childCount; $i++){
                $node['children'][] = $createNode($currentLevel + 1);
            }
            
            return $node;
        };
        
        // 从第一层开始生成树结构
        return $createNode(1);
    }
    /**
     * Undocumented function
     *
     * @param integer $count 生成数据数量
     * @return array
     */
    public static function generateTreeDataByCount(int $count=100,$use_level=false):array{
        $ids_used=[0,0];
        $data = [];
        for($id=1;$id<=$count;++$id){
            $pid = $ids_used[array_rand($ids_used)];
            $level=0;
            $item = [
                'id'=>$id,
                'pid'=>$pid,
            ];
            if($use_level){
                if($pid==0){
                    $level=1;
                }else{
                    $level=$data[$pid]['level']+1;
                }
            }
            $item['level']=$level;

            $data[$id]=$item;
            $ids_used[]=$id;

        }
        
        return $data;
    }
}